#include <Wire.h> 
#include <LiquidCrystal_I2C.h> 
//引用I2C库
//设置LCD1602设备地址0x27
LiquidCrystal_I2C lcd(0x27,16,2); 
//4*4矩阵键盘按键输入模块
  const int numRows = 4;//定义 4 行
const int numCols = 4;//定义 4 列
const int debounceTime = 100;//去抖动时间长度
const char keymap[numRows][numCols]= {//键值，可以按需要更改
 { '/','=','0','<' }, 
 {'*','9','8','7' }, 
 {'-','6','5','4' }, 
 {'+','3','2','1' } 
}; 
const int rowPins[numRows] = {7,6,5,4};//设置硬件对应的引脚
const int colPins[numCols] = {11,10,9,8};

int num = -20;//将输入值（字符型）转换成num（数值型）
int lie = 0;//列数，代表光标处于的下一列的数值，与输入值存到数组和撤销模块有关
int condition = 0;//读取数组分开成两个数的表示变量
int panduan = 0;//判断加减乘除表示变量
double arr1[16] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};//输入值存放的数组
//保存上一次结果的全局变量
long int ans1 = 0;
double ans2 = 0.0;
unsigned long long int ans3 = 0;
// 初始化LCD、设置LCD背景等亮、按键输入等初始化模块
void setup(){  
lcd.init();                  
lcd.backlight();             
  
for(int row = 0; row < numRows; row++){ 
pinMode(rowPins[row],INPUT); 
digitalWrite(rowPins[row],HIGH); 
} 
for(int column = 0;column < numCols; column++){ 
 pinMode(colPins[column],OUTPUT); 
 digitalWrite(colPins[column],HIGH); 
} 
} 
//数据读取、处理、模块
void loop() { 
 char key = getkey(); //获取按键输入值
 if(key !=0)//判断是否按下按键
 {
 num = key - '0';//字符型转换成整型数据
 if(num>=0 && num<= 9)//数字0~9 存放到全局数组arr1中
 {
 lcd.print(num);
 arr1[lie] = (double)num;
 lie++;
 }
 else if(num <0)//加减乘除对应的ASCII码，并且赋值condition存放两个数之间区别的标志，赋值panduan作为标志
 {
  lcd.print(key);
 condition = lie;
 lie++; 
 panduan = num;
 }
 else if(num == 12)//撤销程序模块
 {
 arr1[lie] = -1;
 lcd.print(key);
 lcd.setCursor(lie-1,0);
 lcd.print("  ");
 lcd.setCursor(lie-1,0);
 lie--;
 }
 else if(num == 13 && lie!= 0)//等于号输出模块
 {
 if(panduan == -5)//加法输出模块，”+“ASCII码为-5
 {
  long int temp1 = 0;
  long int temp2 = 0;
  for(int i=0;i<condition;i++)
  {
    temp1 = temp1 * 10 + arr1[i];
  }
  for(int ii= condition+1;ii<16 && arr1[ii]!=-1; ii++)
  {
    temp2 = temp2 * 10 + arr1[ii];
  }
  long int sum = temp1 + temp2;
  lcd.setCursor(0,1);
  lcd.print(key);
  lcd.print(sum);
  ans1 = sum;
 }
  if(panduan == -3)//减法输出模块，”-“ASCII码为-3
  {
  long  int temp1 = 0;
  long int temp2 = 0;
  for(int i=0;i<condition;i++)
  {
    temp1 = temp1 * 10 + arr1[i];
  }
  for(int ii= condition+1;ii<16 && arr1[ii]!=-1; ii++)
  {
    temp2 = temp2 * 10 + arr1[ii];
  }
  long  int sum = temp1 - temp2;
  lcd.setCursor(0,1);
  lcd.print(key);
  lcd.print(sum);
  ans1 = sum;
  }
  if(panduan == -6)//乘法输出模块，”*“ASCII码为-6
  {
    unsigned long long int temp1 = 0;
    unsigned long long int temp2 = 0;
    unsigned long long int sum = 0;
    for(int i=0;i<condition;i++)
  {
    temp1 = temp1 * 10 + arr1[i];
  }
  for(int ii= condition+1;ii<16 && arr1[ii]!=-1; ii++)
  {
    temp2 = temp2 * 10 + arr1[ii];
  }
  sum = temp1 * temp2;
  lcd.setCursor(0,1);
  lcd.print(key);
  int arr2[15] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  int temp3 = 0;
  ans3 = sum;
  while(sum && temp3<15)
  {
    arr2[temp3] = sum % 10;
    temp3++;
    sum /= 10;
  }
  for(int i=14;i>=0;i--)
  if(arr2[i]!=-1)
  lcd.print(arr2[i]);
  if(temp1 == 0 || temp2 ==0)
    lcd.print("0");
  }
  if(panduan == -1)//除法输出模块，”/“ASCII码为-1
  {
    double temp1 = 0.0;
  double temp2 = 0.0;
  for(int i=0;i<condition;i++)
  {
    temp1 = temp1 * 10 + arr1[i];
  }
  for(int ii= condition+1;ii<16 && arr1[ii]!=-1; ii++)
  {
    temp2 = temp2 * 10 + arr1[ii];
  }
  if(temp2 == 0)
  {
    lcd.setCursor(0,1);
    lcd.print("Error!");
  }
  else
  {
  double temp3 = temp1 / temp2;
  lcd.setCursor(0,1);
  lcd.print(key);
  doubleprint(temp3);
  ans2 = temp3;
  }
  
  }

//全局变量初始化，自动清屏模块
  lie = 0;
  condition = 0;
  for(int i=0;i<16;i++)
  arr1[i] = -1;
  delay(2000);
  lcd.clear();
  lcd.setCursor(0,0);
 }

else if(num == 13 && lie== 0)//上次计算结果模显示模块
{
  if(panduan == -5 || panduan == -3)//加减法对应的全局变量显示
  {
    lcd.print("Ans=");
    lcd.setCursor(0,1);
    lcd.print(ans1);
    delay(2000);
    lcd.clear();
    lcd.setCursor(0,0);
  }
  else if(panduan==-6)//乘法对应的全局变量显示
  {  
 lcd.print("Ans=");
 lcd.setCursor(0,1);
    int arr2[15] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  int temp3 = 0;
  unsigned long long int sum = ans3;
  while(sum && temp3<15)
  {
    arr2[temp3] = sum % 10;
    temp3++;
    sum /= 10;
  }
  for(int i=14;i>=0;i--)
  if(arr2[i]!=-1)
  lcd.print(arr2[i]);
  if(ans3 == 0)
  lcd.print("0");
  delay(2000);
    lcd.clear();
    lcd.setCursor(0,0);
  }
  else if(panduan == -1)//除法对应的全局变量显示
  {

    lcd.print("Ans=");
    lcd.setCursor(0,1);
    doubleprint(ans2);
    delay(2000);
    lcd.clear();
    lcd.setCursor(0,0);
  }
}




 
 }
  
 } 
char getkey(){ //读取键值程序
 char key = 0; 
 for(int column = 0;column < numCols; column++){ 
 digitalWrite(colPins[column],LOW); 
 for(int row = 0 ;row < numRows; row++){ 
 if(digitalRead(rowPins[row]) == LOW){ //是否有按键按下
 delay(debounceTime); 
 while(digitalRead(rowPins[row]) == LOW) //等待按键释放
 ; 
 key = keymap[row][column]; 
 } 
 } 
 digitalWrite(colPins[column],HIGH); //De-active the current column 
 } 
 return key; 
 }
void doubleprint(double temp)//6位小数输出显示模块
{
  long zhengshu = (long)temp;
  lcd.print(zhengshu);
  temp = temp - zhengshu;
  lcd.print(".");
  for(int i=0;i<5;i++)
  {
    temp *= 10;
    int zheng = (int)temp;
    lcd.print(zheng);
    temp -= zheng;
  }
  temp*=10;
  //temp+=0.5;
  lcd.print((int)temp);
  return;
}

 
